/*
 * 文件名：OrderServiceImpl.java
 * 版权：
 * 描述：TODO
 * 修改人：zuo liubo
 * 修改时间：2013-3-5 上午10:17:41
 */
package com.scpii.api.service.ec.impl;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import javax.annotation.Resource;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.scpii.api.common.Constants;
import com.scpii.api.common.EcConstants;
import com.scpii.api.common.EcConstants.OrderStatus;
import com.scpii.api.common.EcConstants.PayStatus;
import com.scpii.api.common.EcConstants.ShipStatus;
import com.scpii.api.common.exception.ClientException;
import com.scpii.api.common.exception.EcException;
import com.scpii.api.domain.app.AppConfigs;
import com.scpii.api.domain.ec.Address;
import com.scpii.api.domain.ec.Order;
import com.scpii.api.domain.ec.OrderDetail;
import com.scpii.api.domain.ec.ShoppingCar;
import com.scpii.api.persistence.ec.AddressMapper;
import com.scpii.api.persistence.ec.OrderDetailMapper;
import com.scpii.api.persistence.ec.OrderMapper;
import com.scpii.api.persistence.ec.ShoppingCarMapper;
import com.scpii.api.service.ec.OrderService;
import com.scpii.api.service.ec.PayService;

/**
 * @description 订单处理类
 * @author zuo liubo
 * @date 2013-3-5
 */

@Service("orderService")
@Transactional
public class OrderServiceImpl implements OrderService {
	private Log logger = LogFactory.getLog(OrderServiceImpl.class);

	@Resource
	private OrderMapper orderMapper;
	@Resource
	private ShoppingCarMapper shoppingCarMapper;
	@Resource
	private OrderDetailMapper orderDetailMapper;
	@Resource
	private AddressMapper addressMapper;
	@Resource
	private PayService payService;

	public List<Order> selectOrdersByUserId(Order order, Integer type) {
		switch (type) {
		case 0:
			break;
		case 1:
			order.setPayStatus(EcConstants.PayStatus.PAYMENT_NONE);
			break;
		case 2:
			order.setPayStatus(EcConstants.PayStatus.PAYMENT_SUCCESS);
			order.setOrderStatus(EcConstants.OrderStatus.CONFIRMED);
			break;
		case 3:
			order.setOrderStatus(EcConstants.OrderStatus.TRADE_SUCCESS);
			break;
		default:
			break;
		}
		return orderMapper.selectOrderBySelective(order);
	}

	@Transactional
	public Object submitOrder(Order order, List<ShoppingCar> shoppingCarList) throws EcException {

		// 更新收货地址
		updateAddress(order);
		// 生成订单ID
		Long orderId = generateOrderId();
		order.setOrderId(orderId);
		// 生成订单编号
		String orderSN = generateOrderSn(order);
		order.setOrderSn(orderSN);

		// 如果为积分支付则修改订单支付类型，否则使用用户提交的支付类型
		if (shoppingCarList != null) {
			ShoppingCar car = shoppingCarList.get(0);
			int paymentType = car.getProduct().getPaymentType();
			if (paymentType == EcConstants.PaymentType.PAY_POINT)
				order.setPaymentType(paymentType);
		}
		
		
		// 插入订单信息
		int affectRow = insertOrder(order, shoppingCarList);

		if (affectRow != 1) {
			throw new ClientException();
		}
		// 删除购物车信息
		 deleteShoppingCar(shoppingCarList);
		// 下单后更新产品的库存和订单数
		 Order o = new Order();
		 o.setOrderId(orderId);
		 List<Order> orders = orderMapper.selectOrderBySelective(o);
		 if(orders.size() == 1){
			 o = orders.get(0);
			 payService.updateStoreQuantityAndOrderCount(o,true);
		 }
		return orderId;
	}

	/**
	 * @param order
	 */
	private void updateAddress(Order order) {

		Address address = new Address();
		List<Address> addressList = addressMapper.getAddressByUserId(order.getUserId());
		if (addressList.size() > 0) {
			address = addressList.get(0);
			address.setTitle(order.getTitle());
			address.setAddressLine(order.getAddressLine());
			address.setPhoneNumber(order.getPhoneNumber());
			addressMapper.updateAddressById(address);
		} else {
			address.setAddressId(addressMapper.generateId());
			address.setTargetId(order.getUserId());
			address.setTitle(order.getTitle());
			address.setAddressLine(order.getAddressLine());
			address.setPhoneNumber(order.getPhoneNumber());
			addressMapper.insert(address);
		}
	}

	/**
	 * 删除购物车信息,因为将购物车的数据转移到了订单详情里面,所以要删除该信息
	 * 
	 * @param shopingCarList
	 */
	private void deleteShoppingCar(List<ShoppingCar> shopingCarList) {
		List<Long> carIdList = new ArrayList<Long>();
		for (ShoppingCar car : shopingCarList) {
			carIdList.add(car.getShoppingCarId());
		}
		shoppingCarMapper.deleteShoppingCar(carIdList);
	}

	/**
	 * 插入订单信息
	 * 
	 * @param order
	 *            订单对象
	 * @param shopingCarList
	 *            商品list
	 * @param orderId
	 *            订单ID
	 * @param orderSN
	 *            订单编号
	 * @return
	 */
	private int insertOrder(Order order, List<ShoppingCar> shopingCarList) throws EcException{
		
		order.setOrderStatus(OrderStatus.CONFIRMED); // 订单状态：已确认
		order.setPayStatus(PayStatus.PAYMENT_NONE); // 支付状态：未付款
		order.setShipStatus(ShipStatus.DELIVER_NONE); // 物流状态：未发货

		
		// 在线支付才去查询支付信息，否则直接设置为99999
		if (order.getPaymentType().equals(EcConstants.PaymentType.PAY_ONLINE)) {
			order.setPayType(AppConfigs.Type.ALIPAY);
		} else {
			order.setPayType(9999);
		}

		order.setCreateDt(new Date());
		order.setCreateBy(order.getUserId() + "");

		// 将购物车的数据转换成订单详情
		List<OrderDetail> orderDetails = new ArrayList<OrderDetail>();
		Float totalPrice = 0f;
		for (ShoppingCar car : shopingCarList) {
			OrderDetail orderDetail = new OrderDetail();
			Long orderDetailId = orderDetailMapper.generateOrderDetailId();
			orderDetail.setOrderDetailId(orderDetailId);
			orderDetail.setOrderId(order.getOrderId());
			orderDetail.setAppId(car.getAppId());
			orderDetail.setProduct(car.getProduct());
			// 如果订单中，有一个订单详情项的数量大于库存数时！将请求失败
			if (car.getQuantity() > car.getProduct().getStoreQuantity()) {
				throw new EcException(EcConstants.ERROR_INFO.LESS_THAN_STORE_QUANTITY);
			}
			orderDetail.setQuantity(car.getQuantity());
			orderDetail.setProductName(car.getProduct().getTitle());
			orderDetail.setPrice(car.getProduct().getPrice());
			orderDetail.setListPrice(car.getProduct().getListPrice());
			Float amountPrice = car.getQuantity() * car.getProduct().getPrice();
			totalPrice += amountPrice;
			orderDetail.setPriceAmount(amountPrice);
			orderDetail.setCreateDt(new Date());
			orderDetail.setCreateBy(order.getUserId() + "");
			orderDetail.setNote(car.getNote());

			// 插入订单详情
			orderDetailMapper.insertOrderDetail(orderDetail);
			orderDetails.add(orderDetail);
		}
		// 交易总金额是否一致
		// validateTotalPrice(totalPrice, order.getTotalPrice());
		order.setOrderDetails(orderDetails);
		order.setTotalPrice(totalPrice);

		// 插入订单信息
		return orderMapper.insertOrder(order);
	}


	/**
	 * 计算总价是否一致 不一致就抛出异常
	 * 
	 * @param totalPrice
	 *            用户提交总金额
	 * @param totalPrice2
	 *            系统计算总金额
	 */
	private void validateTotalPrice(float totalPrice, float totalPrice2) {
		logger.info("totalPrice:" + totalPrice + "    totalPrice2:" + totalPrice2);
		if (totalPrice != totalPrice2) {
			throw new EcException(EcConstants.ERROR_INFO.TOTAL_AMOUNT_ERROR);
		}
	}

	/**
	 * 生成订单号 <br>
	 * 订单号规则：0427123 [04表示4月,27表示27号,123表示orderId的最后几位]
	 * 
	 * @param order
	 * @return
	 */
	private String generateOrderSn(Order order) {
		Long orderId = order.getOrderId();
		Calendar now = Calendar.getInstance();
		int month = now.get(Calendar.MONTH) + 1;
		int day = now.get(Calendar.DATE);
		String monthStr = (month < 10) ? "0" + month : "" + month;
		String dayStr = (day < 10) ? "0" + day : "" + day;
		String idStr = (orderId + "").substring(2);
		orderId = Long.parseLong(idStr);
		return monthStr + dayStr + orderId;
	}

	/**
	 * 生成订单ID
	 * 
	 * @return
	 */
	private Long generateOrderId() {
		return orderMapper.generateOrderId();
	}

	@Override
	public void updateOrderStatusToTradeSuccess() {
		Order order = new Order();
		order.setShipStatus(EcConstants.ShipStatus.DELIVER_SUCCESS);
		order.setOrderStatus(EcConstants.OrderStatus.CONFIRMED);
		List<Order> orderList = orderMapper.selectOrderBySelective(order);
		List<Long> orderIdList = new ArrayList<Long>();
		long now = System.currentTimeMillis();
		for (Order o : orderList) {
			if ((now - o.getCreateDt().getTime()) > EcConstants.INTERVAL_DAY) {
				orderIdList.add(o.getOrderId());
			}
		}
		orderMapper.updateOrderStatusToTradeSuccess(orderIdList);
	}

	@Override
	public void checkOrderIsClose() {
		//将订单状态为1和付款状态为0 和 支付方式为1的 设置订单关闭状态
		Order order = new Order();
		order.setOrderStatus(EcConstants.OrderStatus.CONFIRMED);
		order.setPayStatus(EcConstants.PayStatus.PAYMENT_NONE);
		order.setPaymentType(EcConstants.PaymentType.PAY_CASH);
		List<Order> orderList = orderMapper.selectOrderBySelective(order);
		List<Long> orderIdList = new ArrayList<Long>();
		long now = System.currentTimeMillis();
		long expireTime = Integer.parseInt(Constants.ALIPAY_PAY_EXPIRE) * 60 * 1000;
		for (Order o : orderList) {
			if ((now - o.getCreateDt().getTime()) > expireTime) {
				orderIdList.add(o.getOrderId());
				payService.updateStoreQuantityAndOrderCount(order, false);
			}
		}
		orderMapper.updateOrderStatusToTradeClose(orderIdList);
	}

}
